package com.leyou.item.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.leyou.common.constants.MQConstants;
import com.leyou.common.dto.CategoryDTO;
import com.leyou.common.dto.SkuDTO;
import com.leyou.common.dto.SpuDTO;
import com.leyou.common.dto.SpuDetailDTO;
import com.leyou.common.enums.ExceptionEnum;
import com.leyou.common.exceptions.LyException;
import com.leyou.common.utils.BeanHelper;
import com.leyou.common.vo.PageResult;
import com.leyou.item.entity.Sku;
import com.leyou.item.entity.Spu;
import com.leyou.item.entity.SpuDetail;
import com.leyou.item.mapper.SkuMapper;
import com.leyou.item.mapper.SpuDetailMapper;
import com.leyou.item.mapper.SpuMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import static com.leyou.common.constants.MQConstants.Exchange.*;
import static com.leyou.common.constants.MQConstants.RoutingKey.*;


@Service
@Transactional
public class GoodsService {

    @Autowired
    private BrandService brandService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private SpuMapper spuMapper;

    @Autowired
    private SkuMapper skuMapper;

    @Autowired
    private SpuDetailMapper spuDetailMapper;

    @Autowired
    private AmqpTemplate amqpTemplate;

    public PageResult<SpuDTO> spuPageQuery(Integer page, Integer rows, String key, Boolean saleable) {
        Example example = new Example(Spu.class);
        Example.Criteria criteria = example.createCriteria();
        //封装查询条件
        if(StringUtils.isNotBlank(key)) {
            criteria.andLike("name", "%"+key+"%");
        }
        //封装上下架
        if(saleable!=null){
            criteria.andEqualTo("saleable", saleable);
        }
        //设置分页信息
        PageHelper.startPage(page, rows);
        //进行mybatis查询
        List<Spu> spus = spuMapper.selectByExample(example);
        if(CollectionUtils.isEmpty(spus)){
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        //得到分页对象
        PageInfo<Spu> pageInfo = new PageInfo<>(spus);
        //把Spu转成SpuDTO
        List<SpuDTO> spuDTOS = BeanHelper.copyWithCollection(pageInfo.getList(), SpuDTO.class);
        //对spuDTOS进行处理，给品牌名称和分类名称赋值
        handlerCategoryNameAndBrandName(spuDTOS);
        //封装分页结果集
        return new PageResult<>(pageInfo.getTotal(), pageInfo.getPages(), spuDTOS);
    }

    private void handlerCategoryNameAndBrandName(List<SpuDTO> spuDTOS) {
        spuDTOS.forEach(spuDTO -> {//遍历spuDTOS，临时变量为spuDTO
            String categoryNames = categoryService.findCategoryByIds(spuDTO.getCategoryIds())//得到所有分类对象的集合
                    .stream()//把分类集合变成流
                    .map(CategoryDTO::getName)//在map中对每一个对象进行处理，得到商品分类的名称
                    .collect(Collectors.joining("/"));//收集所有的分类名称，并以/连接
            spuDTO.setCategoryName(categoryNames);

            String brandName = brandService.findById(spuDTO.getBrandId()).getName();
            spuDTO.setBrandName(brandName);
        });
    }

    public void saveGoods(SpuDTO spuDTO) {
        try {
            //保存Spu
            //把SpuDTO转成Spu
            Spu spu = BeanHelper.copyProperties(spuDTO, Spu.class);
            spuMapper.insertSelective(spu);

            //保存SpuDetail
            SpuDetailDTO spuDetailDTO = spuDTO.getSpuDetail();
            SpuDetail spuDetail = BeanHelper.copyProperties(spuDetailDTO, SpuDetail.class);
            spuDetail.setSpuId(spu.getId());
            spuDetailMapper.insertSelective(spuDetail);

            //保存Sku集合
            List<SkuDTO> skuDTOS = spuDTO.getSkus();
            List<Sku> skus = BeanHelper.copyWithCollection(skuDTOS, Sku.class);
            //遍历skus，给每一个Sku中的spuId赋值
            skus.forEach(sku -> {
                sku.setSpuId(spu.getId());
                sku.setCreateTime(new Date());
                sku.setUpdateTime(new Date());
            });
            skuMapper.insertList(skus);
        }catch (Exception e){
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }
    }

    public void updateSaleable(Long id, Boolean saleable) {
        try {
            //修改spu中的上下架
            Spu record = new Spu();
            record.setId(id);
            record.setSaleable(saleable);
            spuMapper.updateByPrimaryKeySelective(record);

            //封装要修改的数据
            Sku sku = new Sku();
            sku.setEnable(saleable);
            //封装修改的条件
            Example example = new Example(Sku.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("spuId", id);
            //修改sku中的enable字段, update tb_sku set enable=#{} where spu_id=#{}
            skuMapper.updateByExampleSelective(sku, example);

            //向队列发送消息
            String routingKey = saleable?ITEM_DOWN_KEY : ITEM_DOWN_KEY;
            amqpTemplate.convertAndSend(ITEM_EXCHANGE_NAME, routingKey,id);
        }catch (Exception e){
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }
    }

    public SpuDetailDTO findSpuDetailBySpuId(Long id) {
        SpuDetail spuDetail = spuDetailMapper.selectByPrimaryKey(id);
        if(spuDetail==null){
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        return BeanHelper.copyProperties(spuDetail, SpuDetailDTO.class);
    }

    public List<SkuDTO> findSkusBySpuId(Long id) {
        Sku record = new Sku();
        record.setSpuId(id);
        List<Sku> skus = skuMapper.select(record);
        if(CollectionUtils.isEmpty(skus)){
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        return BeanHelper.copyWithCollection(skus, SkuDTO.class);
    }

    public void updateGoods(SpuDTO spuDTO) {
        try {
            //修改spu
            //把SpuDTO转成Spu
            Spu spu = BeanHelper.copyProperties(spuDTO, Spu.class);
            //设置成下架
            spu.setSaleable(false);
            //修改操作
            spuMapper.updateByPrimaryKeySelective(spu);

            //修改SpuDetail
            //获取SpuDetail
            SpuDetailDTO spuDetailDTO = spuDTO.getSpuDetail();
            //转成SpuDetail
            SpuDetail spuDetail = BeanHelper.copyProperties(spuDetailDTO, SpuDetail.class);
            //修改操作
            spuDetailMapper.updateByPrimaryKeySelective(spuDetail);

            //删除当前Spu下所有的Sku
            Sku record = new Sku();
            record.setSpuId(spuDTO.getId());
            skuMapper.delete(record);
            //保存Sku集合
            List<SkuDTO> skuDTOS = spuDTO.getSkus();
            List<Sku> skus = BeanHelper.copyWithCollection(skuDTOS, Sku.class);
            //遍历skus，给每一个Sku中的spuId赋值
            skus.forEach(sku -> {
                sku.setSpuId(spu.getId());
                sku.setEnable(false);
                sku.setCreateTime(new Date());
                sku.setUpdateTime(new Date());
            });
            skuMapper.insertList(skus);
        }catch (Exception e){
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }

    }

    public SpuDTO findSpuBySpuId(Long id) {
        try {
            Spu spu = spuMapper.selectByPrimaryKey(id);
            SpuDTO spuDTO = BeanHelper.copyProperties(spu, SpuDTO.class);

            SpuDetailDTO spuDetailDTO = findSpuDetailBySpuId(spuDTO.getId());
            spuDTO.setSpuDetail(spuDetailDTO);

            List<SkuDTO> skusDTO = findSkusBySpuId(spuDTO.getId());
            spuDTO.setSkus(skusDTO);
            return spuDTO;
        }catch (Exception e){
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }

    }
}
